package com.gwtserializer.dispatch.annotation.helper;

import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;


public class GenHelper extends ClassGenerationHelper {

	public GenHelper(Writer sourceWriter) {
		super(sourceWriter);
	}

	public String capitalize(String s) {
		if (s.length() == 0)
			return s;
		return s.substring(0, 1).toUpperCase() + s.substring(1);
	}

	public boolean isCollection(TypeMirror type) {
		String typeName = type.toString();
		if (typeName.contains("List")) {
			return true;
		}
		if (typeName.contains("Set")) {
			return true;
		} 
		if (typeName.contains("Map")) {
			return true;
		}
		return false;
	}

	public String getInstanceCollection(TypeMirror type) {
		String typeName = type.toString();
		DeclaredType dtype = (DeclaredType) type;
		if (typeName.contains("List")) {
			return ArrayList.class.getCanonicalName() + "<" + dtype.getTypeArguments().get(0) + ">";
		}
		if (typeName.contains("Set")) {
			return HashSet.class.getCanonicalName() + "<" + dtype.getTypeArguments().get(0) + ">";
		}
		if (typeName.contains("Map")) {
			return HashMap.class.getCanonicalName() + "<" + dtype.getTypeArguments().get(0) + ","
					+ dtype.getTypeArguments().get(1) + ">";
		}
		return null;
	}

	public String determineAccessorName(VariableElement fieldElement) {
		String name;
		if (fieldElement.asType().toString().equals(java.lang.Boolean.class.getSimpleName().toLowerCase())) {
			name = "is";
		} else {
			name = "get";
		}
		name += fieldElement.getSimpleName().toString().substring(0, 1).toUpperCase();
		name += fieldElement.getSimpleName().toString().substring(1);

		return name;
	}

	public String determineType(TypeMirror type) {
		String typeName = type.toString();
		if (typeName.equals("byte") || typeName.contains("Byte")) {
			return java.lang.Byte.class.getSimpleName();
		}
		if (typeName.equals("short") || typeName.contains("Short")) {
			return java.lang.Short.class.getSimpleName();
		}
		if (typeName.equals("int") || typeName.contains("Integer")) {
			return "Int";
		}
		if (typeName.equals("long") || typeName.contains("Long")) {
			return java.lang.Long.class.getSimpleName();
		}
		if (typeName.equals("float") || typeName.contains("Float")) {
			return java.lang.Float.class.getSimpleName();
		}
		if (typeName.equals("double") || typeName.contains("Double")) {
			return java.lang.Double.class.getSimpleName();
		}
		if (typeName.equals("char") || typeName.contains("Character")) {
			return "Char";
		}
		if (typeName.equals("boolean") || typeName.contains("Boolean")) {
			return java.lang.Boolean.class.getSimpleName();
		}
		if (typeName.contains("String")) {
			return java.lang.String.class.getSimpleName();
		} else {
			return Object.class.getSimpleName();
		}
	}

	@Override
	public boolean isPrimitive(TypeMirror type) {
		String typeName = type.toString();
		if (typeName.equals("byte") || typeName.contains("Byte")) {
			return true;
		}
		if (typeName.equals("short") || typeName.contains("Short")) {
			return true;
		}
		if (typeName.equals("int") || typeName.contains("Integer")) {
			return true;
		}
		if (typeName.equals("long") || typeName.contains("Long")) {
			return true;
		}
		if (typeName.equals("float") || typeName.contains("Float")) {
			return true;
		}
		if (typeName.equals("double") || typeName.contains("Double")) {
			return true;
		}
		if (typeName.equals("char") || typeName.contains("Character")) {
			return true;
		}
		if (typeName.equals("boolean") || typeName.contains("Boolean")) {
			return true;
		}
		if (typeName.contains("String")) {
			return true;
		}
		if (typeName.contains("Object")) {
			return true;
		}
		return false;
	}

}
